package com.zz.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zz.common.Log;
import com.zz.common.R;
import com.zz.dto.ActivityDto;
import com.zz.entity.Activity;
import com.zz.entity.ESActivity;
import com.zz.service.ActivityService;
import com.zz.service.ESActivityService;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Delete;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户活动管理
 * @author 周紫
 */
@RestController
@RequestMapping("/activity")
@Slf4j
@CrossOrigin
@Validated
public class ActivityController {

    @Autowired
    private ElasticsearchRestTemplate elasticsearchTemplate;

    @Autowired
    private ESActivityService esActivityService;

    @Autowired
    private ActivityService activityService;

    /**
     * 活动信息分页查询
     * 周紫
     *
    * */
    @GetMapping("/page")
    @Cacheable(cacheNames="activityCache#86400",key = "'activity'",sync = true)
    @Log(title = "分页展示活动信息",dataLocationType = "link")
    @Transactional
    public R<Page> page(@RequestParam @NotNull(message = "起始页码不能为空") int page,
                        @RequestParam @NotNull(message = "每页最大数不能为空") int pageSize,
                        @Nullable @RequestParam String name) {
        log.info("name=>{}",name);
        return activityService.page(page, pageSize, name);
    }

    /**
    * 用户报名参加活动
     * @param activity
     * 测试成功
    */
    @PostMapping("/applyActivity")
    @Log(title = "用户报名参加活动", dataLocationType = "body")
    @Transactional
    public R<String> applyActivity(@RequestBody @Validated(value = {Delete.class}) Activity activity,
                                   HttpServletRequest request){
        return activityService.applyActivity(activity,request);

    }

    @GetMapping("/showLatestActivity")
    @Log(title = "展示距今最近时间的活动", dataLocationType = "link")
    public R<List<ActivityDto>> showLatestActivity(@RequestParam @NotNull(message = "start不能为空") int start,
                                                   @RequestParam @NotNull(message = "end不能为空") int end){
        return activityService.showLatestActivity(start,end);
    }

    @GetMapping("/activityInfo")
    @Log(title = "查看活动详情", dataLocationType = "link")
    public R<ActivityDto> activityInfo(@NotNull(message = "活动编码不能为空") int activityId) {
        return activityService.activityInfo(activityId);
    }

    /**
    * 根据分类展示活动
     * @param classify
    * */
    @GetMapping("/showByClassify")
    @Log(title = "根据分类展示活动", dataLocationType = "link")
    public R<List<ActivityDto>> showByClassify(@Nullable String classify){
        return activityService.showByClassify(classify);
    }


    //---------------------------------ES----------------------------------------------
    @GetMapping("/getHightByName")
    public R<List<ESActivity>> getHightByName(String value){

        //根据一个值查询多个字段  并高亮显示  这里的查询是取并集，即多个字段只需要有一个字段满足即可
        //需要查询的字段
        BoolQueryBuilder boolQueryBuilder= QueryBuilders.boolQuery()
                .should(QueryBuilders.matchQuery("name",value));

        //构建高亮查询
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(boolQueryBuilder)
                .withHighlightFields(new HighlightBuilder.Field("name"))
                .withHighlightBuilder(new HighlightBuilder().preTags("<span style='color:red'>").postTags("</span>"))
                .build();
        //查询
        SearchHits<ESActivity> search = elasticsearchTemplate.search(searchQuery, ESActivity.class);
        //得到查询返回的内容
        List<SearchHit<ESActivity>> searchHits = search.getSearchHits();
        //设置一个最后需要返回的实体类集合
        List<ESActivity> activities = new ArrayList<>();
        //遍历返回的内容进行处理
        for(SearchHit<ESActivity> searchHit:searchHits){
            //高亮的内容
            Map<String, List<String>> highlightFields = searchHit.getHighlightFields();
            //将高亮的内容填充到content中
            searchHit.getContent().setName(highlightFields.get("name")==null ? searchHit.getContent().getName():highlightFields.get("name").get(0));
            //放到实体类中
            activities.add(searchHit.getContent());
        }
        return R.success(activities);
    }


    @PostMapping("/esAdd")
    public Map<String, String> esAdd(String code) {
        elasticsearchTemplate.putMapping(ESActivity.class);
        esActivityService.addToES(code);
        Map<String, String> map = new HashMap<>();
        map.put("msg", "esAdd ok");
        return map;
    }
    @PostMapping("/esUpdate")
    public Map<String, String> esUpdate(@RequestBody ESActivity esActivity) {
        String msg = esActivityService.esUpdate(esActivity);
        Map<String, String> map = new HashMap<>();
        map.put("msg", "esUpdate "+msg);
        return map;
    }
    @PostMapping("/esDelete")
    public Map<String, String> esDelete(@RequestBody ESActivity esActivity) {
        esActivityService.esDelete(esActivity);
        Map<String, String> map = new HashMap<>();
        map.put("msg", "esDelete ok");
        return map;
    }

}
